#include "polyeval.h"

/**
 * @brief polyeval 利用 Horner 公式计算多项式的值
 * @param p 多项式的系数 a0, a1, a2,\cdots a_n
 * @param n 多项式的次数 n
 * @param x 要计算的值
 * @return 返回多项式在 x 点的值
 */
double polyeval(double p[], int n, double x)
{
    double r = 0;
    while (n >= 0)
    {
        r = p[n] + r * x;
        n--;
    }
    return r;
}

/**
 * @brief polydiv 计算 p(x) / (x - a) 的商和余数
 * @param p 多项式的系数，p0 .. pn
 * @param n 多项式的次数
 * @param q 结果 r, q0, q1, ... qn-1 ,注意第一个数是余数
 * @return 返回的也是余数，也等于 p(a) 的值
 */
double polydiv(double p[], int n, double a, double q[])
{
    q[n] = p[n];
    for(int i = n - 1; i >= 0; i--)
    {
        q[i] = p[i] + a * q[i+1];
    }
    return q[0];
}

/**
 * @brief polydiv2 计算 p(x) / (x - a) 的除数和余数。
 * @param p 多项式的系数，p0 .. pn，同时计算结束后也返回 r, q0, q1, ... qn-1
 * @param n 多项式的次数
 * @param a
 * @return 返回的也是余数，也等于 p(a) 的值
 */
double polydiv2(double p[], int n, double a)
{
    for(int i = n - 1; i >= 0; i--)
    {
        p[i] = p[i] + a * p[i+1];
    }
    return p[0];
}

/**
 * @brief polyshift 将 x 的多项式变换为 (x-a) 的多项式
 * @param p 多项式的系数，p0 .. pn, 计算结束后返回新的系数
 * @param n 多项式的次数
 * @param a 将  (x - a)
 */
void polyshift(double p[], int n, double a)
{
    for(int i = n; i >= 1; i--)
    {
        polydiv2(p, i, a);
        p++;
    }
}
